package com.ctshk.rpc.order.season.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.IsDeletedCode;
import com.ctshk.common.enums.SeasonIndividualType;
import com.ctshk.common.enums.SeasonType;
import com.ctshk.common.enums.SystemError;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.DateUtil;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.common.utils.SeasonOrderManager;
import com.ctshk.common.utils.SnowflakeIdWorker;
import com.ctshk.rpc.order.season.dto.*;
import com.ctshk.rpc.order.season.entity.SeasonOrder;
import com.ctshk.rpc.order.season.entity.SeasonOrderReceipt;
import com.ctshk.rpc.order.season.mapper.SeasonOrderMapper;
import com.ctshk.rpc.order.season.mapper.SeasonOrderReceiptMapper;
import com.ctshk.rpc.order.season.req.SeasonOrderReceiptReq;
import com.ctshk.rpc.order.season.service.ISeasonOrderCollectionService;
import com.ctshk.rpc.order.season.service.ISeasonOrderReceiptService;
import com.ctshk.rpc.order.season.service.ISeasonOrderService;
import com.ctshk.rpc.order.season.service.ISeasonProductOrderTouristTypeService;
import com.ctshk.rpc.season.dto.FixedSeasonDetailsDTO;
import com.ctshk.rpc.season.service.ISeasonFixedProductService;
import com.ctshk.rpc.stamp.req.LevyRequest;
import com.ctshk.rpc.system.dto.SysDepartmentDTO;
import com.ctshk.rpc.system.dto.UserDTO;
import com.ctshk.rpc.system.service.ISysDepartmentService;
import com.ctshk.rpc.system.service.ISysUserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.StringJoiner;

/**
 * <p>
 * 套票订单-收据表 服务实现类
 * </p>
 *
 * @author 杨林
 * @since 2021-03-24
 */
@DubboService
public class SeasonOrderReceiptServiceImpl extends ServiceImpl<SeasonOrderReceiptMapper, SeasonOrderReceipt> implements ISeasonOrderReceiptService {

    @Autowired
    private SeasonOrderReceiptMapper seasonOrderReceiptMapper;

    @Autowired
    private SeasonOrderMapper orderMapper;

    @DubboReference
    private ISysUserService iSysUserService;

    @DubboReference
    private ISysDepartmentService iSysDepartmentService;

    @DubboReference
    private ISeasonOrderService seasonOrderService;


    @DubboReference
    private ISeasonOrderCollectionService collectionService;

    @DubboReference
    private ISeasonProductOrderTouristTypeService touristTypeService;

    @DubboReference
    private ISeasonFixedProductService productService;

    //印花税 服务接口
//    @DubboReference
//   private ILevyService levyService;


    /* @MethodName: 套票收据详情
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/31 10:05
     **/
    @Override
    public Result<ReceiptInfoDTO> getReceiptInfo(Long id, TokenUser user) {
        SeasonOrder order = orderMapper.selectById(id);
        if (Objects.isNull(order)) {
            return Result.failed(SystemError.SEASON_TICKET_20021);
        }
        SeasonOrderReceipt receipt = getReceipt(id);
        if (Objects.isNull(receipt)) {
            return Result.failed(SystemError.SYS_411);
        }
        //樱花税
        BigDecimal stampTaxAmount = getStampTaxAmount(order);
        Integer num = 0;
        //不等0  有一个发票
        if (stampTaxAmount.compareTo(BigDecimal.ZERO) != 0) {
            num++;
        }
        //保险费用
        BigDecimal insuranceAmount = order.getInsuranceAmount();
        if (stampTaxAmount.compareTo(BigDecimal.ZERO) != 0) {
            num++;
            stampTaxAmount.add(insuranceAmount.multiply(SeasonOrderManager.TAX_RATE));
        }
        LevyRequest request = new LevyRequest();
        request.setReceiptNumber(receipt.getReceiptNo());
        request.setNameOfTravelerPayer(receipt.getSales());
        request.setPremiumReceived(String.valueOf(stampTaxAmount));
        request.setLast4DigitOfContactPhoneNumber(receipt.getPhone().substring(receipt.getPhone().length() - 4));
        request.setDepartureDate(DateUtil.fmtLocalDate(order.getDepartDate(), "yyyy-MM-dd"));
//          Result<LevyDTO> levyDTOResult = levyService.levyEFrank(request);
//          if (!levyDTOResult.isSuccess() || levyDTOResult.getData() == null) {
//            throw new BusinessException(SystemError.SEASON_TICKET_20032);
//          }
        //         LevyDTO levyDTO = levyDTOResult.getData();
        order.setStampTaxAmount(stampTaxAmount);
        order.setStampTaxNumber(num);
        orderMapper.updateById(order);

        ReceiptInfoDTO dto = EntityUtil.copy(receipt, ReceiptInfoDTO.class);
        SeasonSearchOrderDTO detailsDTO = seasonOrderService.getOrderInfoById(id);
        //    dto.setStampTaxJson(Base64.getEncoder().encodeToString(levyDTO.getLevystamp()));
        dto.setSeasonName(detailsDTO.getProductName());//套票名称
        //出发日期
        dto.setDepartureDate(detailsDTO.getDepartDate().toString() + " " + detailsDTO.getTravelDays());
        //预订须知
        dto.setBookingInformation(detailsDTO.getBookingInformation());
        dto.setSeasonAmount(order.getSeasonAmount());
        dto.setReceivableAmount(order.getReceivableAmount());
        dto.setPayAmount(order.getOrderAmount().subtract(order.getTotalCouponAmount()));
        List<SeasonOrderPayDTO> payListist = collectionService.getCollectionListById(id);
        dto.setSeasonOrderPayDTOList(payListist);
        List<SeasonProductDTO> productList = getProductInfo(detailsDTO);
        dto.setProductDTOList(productList);
        //收款信息
        return Result.success(dto);
    }

    /* @MethodName: 获取税费信息
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/4/1 17:50
     **/
    private BigDecimal getStampTaxAmount(SeasonOrder order) {
        //印花税
        BigDecimal stampTaxAmount = BigDecimal.ZERO;
        Integer productType = order.getProductType();
        //固定套票才有印花税
        if (SeasonType.PRODUCT_FIXED_TYPE.getCode() == productType) {
            Long productId = order.getProductId();
            FixedSeasonDetailsDTO fixedSeason = productService.getFixedProductBaseDTO(productId);
            //出发城市Id
            Long depCityId = fixedSeason.getDepCityId();
            //到达城市id
            Long arrCityId = fixedSeason.getArrCityId();
            Long hkId = SeasonOrderManager.AREA_HK;
            if (hkId.equals(depCityId) && !hkId.equals(arrCityId)) {
                //出发地为香港，目的地非香港
                String productFlag = order.getSeasonPackageProductFlag();
                if (isContainTraffic(productFlag) && isContainProduct(productFlag)) {//包含酒店
                    BigDecimal subtract = order.getSeasonAmount().subtract(order.getTotalCouponAmount());//套票金额减去优惠总金额
                    stampTaxAmount = subtract.multiply(SeasonOrderManager.TAX_RATE);
                }
            }
        }
        return stampTaxAmount;
    }


    /* @MethodName: 是否包含交通产品
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/5/7
     **/
    public boolean isContainTraffic(String productFlag) {
        if (productFlag.contains(SeasonIndividualType.AIR.getKey())
                || productFlag.contains(SeasonIndividualType.BUS.getKey())
                || productFlag.contains(SeasonIndividualType.SHIP.getKey())
                || productFlag.contains(SeasonIndividualType.TRAIN.getKey())) {
            return true;
        } else {
            return false;
        }
    }

    /* @MethodName: 是否包含其他产品
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: Eric
     * @Date:2021/5/7
     **/
    public boolean isContainProduct(String productFlag) {
        if (productFlag.contains(SeasonIndividualType.HOTEL.getKey())
                || productFlag.contains(SeasonIndividualType.SCENIC.getKey())
                || productFlag.contains(SeasonIndividualType.LOCALFUN.getKey())
                || productFlag.contains(SeasonIndividualType.COMMODITY.getKey())) {
            return true;
        } else {
            return false;
        }
    }

    /* @MethodName: 订单收款上的产品信息
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/31 14:01
     **/
    public List<SeasonProductDTO> getProductInfo(SeasonSearchOrderDTO detailsDTO) {
        List<SeasonProductDTO> resultList = new LinkedList<>();
        List<SeasonProductOrderAirDTO> airList = detailsDTO.getAirList();
        for (SeasonProductOrderAirDTO air : airList) {
            SeasonProductDTO dto = new SeasonProductDTO();
            dto.setProduct("机票");
            StringJoiner sj = new StringJoiner(air.getDepCityName());
            sj.add("-").add(air.getArrCityName()).add("  ");
            sj.add(air.getFlightNumber());
            dto.setProductName(sj.toString());
            dto.setDateTime(air.getArrTime());
            //获取旅客数量
            Integer number = touristTypeService.getTouristNumber(detailsDTO.getId(), 1);
            dto.setNumber(number);
            resultList.add(dto);
        }

        List<SeasonProductOrderBusDTO> busList = detailsDTO.getBusList();
        for (SeasonProductOrderBusDTO bus : busList) {
            SeasonProductDTO dto = new SeasonProductDTO();
            dto.setProduct("巴士票");
            StringJoiner sj = new StringJoiner(bus.getDepCityName());
            sj.add("-").add(bus.getArrCityName()).add("  ");
            sj.add(bus.getShiftCode());
            dto.setProductName(sj.toString());
            dto.setDateTime(bus.getDepTime());
            //获取旅客数量
            Integer number = touristTypeService.getTouristNumber(detailsDTO.getId(), 3);
            dto.setNumber(number);
            resultList.add(dto);
        }

        List<SeasonProductOrderHotelDTO> hotelList = detailsDTO.getHotelList();
        for (SeasonProductOrderHotelDTO hotel : hotelList) {
            SeasonProductDTO dto = new SeasonProductDTO();
            dto.setProduct("酒店");
            dto.setProductName(hotel.getHotelProductName());
            dto.setDateTime(hotel.getOccupancyDate().atStartOfDay());
            //获取旅客数量
            Integer number = touristTypeService.getTouristNumber(detailsDTO.getId(), 2);
            dto.setNumber(number);
            Long cz = ChronoUnit.DAYS.between(hotel.getOccupancyDate(), hotel.getDepartureDate());
            dto.setDayNumber(cz.intValue());
            resultList.add(dto);
        }

        List<SeasonProductOrderLocalFunDTO> localFunList = detailsDTO.getLocalFunList();
        for (SeasonProductOrderLocalFunDTO localFun : localFunList) {
            SeasonProductDTO dto = new SeasonProductDTO();
            dto.setProduct("当地玩乐");
            dto.setProductName(localFun.getSpecificationName());
            dto.setDateTime(localFun.getProductDate().atStartOfDay());
            dto.setNumber(localFun.getNumber());
            resultList.add(dto);
        }

        List<SeasonProductOrderScenicDTO> scenicList = detailsDTO.getScenicList();
        for (SeasonProductOrderScenicDTO scenic : scenicList) {
            SeasonProductDTO dto = new SeasonProductDTO();
            dto.setProduct("景点门票");
            dto.setProductName(scenic.getScenicName());
            dto.setDateTime(scenic.getTicketDate().atStartOfDay());
            dto.setNumber(scenic.getTicketNumber());
            resultList.add(dto);
        }

        List<SeasonProductOrderShipDTO> shipList = detailsDTO.getShipList();
        for (SeasonProductOrderShipDTO ship : shipList) {
            SeasonProductDTO dto = new SeasonProductDTO();
            dto.setProduct("船票");
            StringJoiner sj = new StringJoiner(ship.getDepCityName());
            sj.add("-").add(ship.getArrCityName()).add("  ");
            sj.add(ship.getVoyage());
            dto.setProductName(sj.toString());
            dto.setDateTime(ship.getDepTime());
            //获取旅客数量
            Integer number = touristTypeService.getTouristNumber(detailsDTO.getId(), 4);
            dto.setNumber(number);
            resultList.add(dto);
        }

        List<SeasonProductOrderTrainDTO> trainList = detailsDTO.getTrainList();
        for (SeasonProductOrderTrainDTO train : trainList) {
            SeasonProductDTO dto = new SeasonProductDTO();
            dto.setProduct("火车票");
            StringJoiner sj = new StringJoiner(train.getDepStationName());
            sj.add("-").add(train.getArrStationName()).add("  ");
            sj.add(train.getTrainNumber());
            dto.setProductName(sj.toString());
            dto.setDateTime(train.getDepTime());
            //获取旅客数量
            Integer number = touristTypeService.getTouristNumber(detailsDTO.getId(), 5);
            dto.setNumber(number);
            resultList.add(dto);
        }
        List<SeasonProductOrderCommodityDTO> commodityList = detailsDTO.getCommodityList();
        for (SeasonProductOrderCommodityDTO commodity : commodityList) {
            SeasonProductDTO dto = new SeasonProductDTO();
            dto.setProduct("景点门票");
            dto.setProductName(commodity.getSpecificationName());
            dto.setDateTime(commodity.getProductDate().atStartOfDay());
            dto.setNumber(commodity.getNumber());
            resultList.add(dto);
        }

        return resultList;
    }


    /* @MethodName: 保存套票详收据
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/31 10:40
     **/
    @Override
    public Result addReceipt(Long id, TokenUser user) {
        UserDTO userDTO = iSysUserService.loadUserByParam(user.getId(), 1);
        SysDepartmentDTO sysDepartmentDTO = iSysDepartmentService.queryByUserId(user.getId());

        SeasonOrderReceipt seasonOrderReceipt = new SeasonOrderReceipt();
        seasonOrderReceipt.setId(SnowflakeIdWorker.nextId());
        seasonOrderReceipt.setIsDeleted(IsDeletedCode.NO.getCode());
        //收据单号
        seasonOrderReceipt.setReceiptNo(SeasonOrderManager.getReceiptNumer(sysDepartmentDTO.getDeptCode(), userDTO.getEmployeeNumber()));
        seasonOrderReceipt.setCreateId(user.getId());
        seasonOrderReceipt.setGmtCreate(LocalDateTime.now());
        //牌照号码
        seasonOrderReceipt.setLicenseNo(SeasonOrderManager.LICENSE_NO);
        //咨询电话
        seasonOrderReceipt.setSupportNo(SeasonOrderManager.SUPPORT_NO);
        //查询号码
        seasonOrderReceipt.setQueryNo(SeasonOrderManager.getQueryNo());
        seasonOrderReceiptMapper.insert(seasonOrderReceipt);
        return Result.success(seasonOrderReceipt);
    }

    /* @MethodName: 编辑收据 信息
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/31 15:42
     **/
    @Override
    public Result editReceipt(SeasonOrderReceiptReq req, TokenUser user) {
        SeasonOrderReceipt receipt = getReceipt(req.getId());
        if (Objects.isNull(receipt)) {
            return Result.failed(SystemError.SYS_411);
        }
        receipt.setGuest(req.getGuest());
        receipt.setPhone(req.getPhone());
        receipt.setRemark(req.getRemark());
        receipt.setAttention(req.getAttention());
        receipt.setModifiedId(user.getId());
        receipt.setGmtModified(LocalDateTime.now());
        seasonOrderReceiptMapper.updateById(receipt);
        return Result.success();
    }


    /* @MethodName: 获取收据信息 根据订单号
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/31 11:52
     **/
    public SeasonOrderReceipt getReceipt(Long orderId) {
        return seasonOrderReceiptMapper.selectOne(
                new QueryWrapper<SeasonOrderReceipt>().lambda()
                        .eq(SeasonOrderReceipt::getOrderId, orderId)
                        .eq(SeasonOrderReceipt::getIsDeleted, IsDeletedCode.NO.getCode())
        );

    }


}
